package com.yj.audio_output_device_new;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.IntentFilter;

import androidx.annotation.NonNull;

import com.yj.audio_output_device_new.callback.impl.CallbackImpl;
import com.yj.audio_output_device_new.receiver.BleConnectionReceiver;
import com.yj.audio_output_device_new.util.ble.BleUtil;

import java.lang.ref.WeakReference;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** AudioOutputDeviceNewPlugin */
public class AudioOutputDeviceNewPlugin implements FlutterPlugin, MethodCallHandler,
        EventChannel.StreamHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;

  private EventChannel eventChannel;
  private EventChannel.EventSink eventSink;

  private Context context;
  private WeakReference<Context> contextWeakReference;

  private BleConnectionReceiver bleConnectionReceiver;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    context = flutterPluginBinding.getApplicationContext();
    contextWeakReference = new WeakReference<>(context);

    BleUtil.init(contextWeakReference);

    bleConnectionReceiver = new BleConnectionReceiver();
    IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    context.registerReceiver(bleConnectionReceiver, intentFilter);

    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "audio_output_device_new");
    channel.setMethodCallHandler(this);

    eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "audio_output_device_new/event");
    eventChannel.setStreamHandler(this);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    switch (call.method){
      case "getPlatformVersion":
        result.success("Android " + android.os.Build.VERSION.RELEASE);
        break;
      case "getA2dpConnectedDevices":
        result.success(BleUtil.getA2dpConnectedDevices());
        break;
      default:
        result.notImplemented();
        break;
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    if(bleConnectionReceiver != null){
      context.unregisterReceiver(bleConnectionReceiver);
    }

    BleUtil.close();

    contextWeakReference = null;
    context = null;

    channel.setMethodCallHandler(null);
    channel = null;

    eventChannel.setStreamHandler(null);
    eventChannel = null;
  }

  @Override
  public void onListen(Object arguments, EventChannel.EventSink events) {
    eventSink = events;
    CallbackImpl.getInstance().setEventSink(eventSink);
  }

  @Override
  public void onCancel(Object arguments) {
    eventSink.endOfStream();
    eventSink = null;
  }
}
